package com.jianan.mis.service;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.jianan.mis.data.dao.OsConsultationDao;
import com.jianan.mis.data.dao.base.PageControl;
import com.jianan.mis.data.domain.OsConsultation;
import com.jianan.mis.data.domain.OsConsultationState;

public class OsConsultationServiceImpl implements OsConsultationService {

	private OsConsultationDao osConsultationDao;
	
	public Serializable save(OsConsultation osConsultation) {
		return osConsultationDao.save(osConsultation);
	}

	public void update(OsConsultation osConsultation) {
		osConsultation.setUpdateDate(new Date());
		osConsultationDao.saveOrUpdate(osConsultation);
	}

	public void remove(OsConsultation osConsultation) {
		osConsultationDao.remove(osConsultation);
	}

	public List<OsConsultation> getAll() {
		return osConsultationDao.getAll(OsConsultation.class, "id", true);
	}

	@SuppressWarnings("unchecked")
	public List<OsConsultation> getByStates(int[] states) {
		Criteria criteria = osConsultationDao.createCriteria(OsConsultation.class);
		for(int state : states) {
			criteria.add(Restrictions.eq("State", state));
		}
		return criteria.list();
	}

	public void pageQuery(PageControl pageControl, Map conditions) {
		Criteria criteria = osConsultationDao.createCriteria(OsConsultation.class);
		if (conditions.get("onlyConsultantId") != null) {
			Integer onlyConsultantId = (Integer) conditions.get("onlyConsultantId");
			criteria.add(
				Expression.or(
					Expression.isNull("Consultant.id"), Expression.eq("Consultant.id", onlyConsultantId)));
					//Expression.or(, 
						//Expression.or(Expression.eq("State", OsConsultationState.UNREASSIGNED), 
							//Expression.eq("State", OsConsultationState.REASSIGNED))))); 
		} else if (conditions.get("consultantId") != null) {
			Integer consultantId = (Integer) conditions.get("consultantId");
			criteria.add(Expression.eq("Consultant.id", consultantId));
		}
		if (conditions.get("countryId") != null) {
			Integer countryId = (Integer) conditions.get("countryId");
			criteria.add(Expression.eq("CountryIntent.id", countryId));
		}
		if (conditions.get("from") != null) {
			Date from = (Date) conditions.get("from");
			criteria.add(Restrictions.ge("CreateDate", from));
		}
		if (conditions.get("to") != null) {
			Date to = (Date) conditions.get("to");
			criteria.add(Restrictions.le("CreateDate", to));
		}
		if (conditions.get("state") != null) {
			Integer state = (Integer) conditions.get("state");
			switch (state) {
			case 0:
				criteria.add(Restrictions.eq("State", OsConsultationState.UNSIGNED));
				break;
			case 1:
				criteria.add(Restrictions.eq("State", OsConsultationState.AUDITING));
				break;
			case 2:
				criteria.add(Restrictions.eq("State", OsConsultationState.UNREASSIGNED));
				break;
			case 3:
				criteria.add(Restrictions.eq("State", OsConsultationState.REASSIGNED));
				break;
			case 4:
				criteria.add(Restrictions.eq("State", OsConsultationState.UNINTENTIONAL));
				break;
			}
		}
		if (conditions.get("restricted") != null) {
			criteria.add(Restrictions.ne("State", OsConsultationState.UNINTENTIONAL));
		}
		criteria.add(Restrictions.ne("State", OsConsultationState.SIGNED));
		criteria.addOrder(Order.asc("id"));
		pageControl = osConsultationDao.pagedQuery(criteria, pageControl);
	}

	public List getStat(int groupType, int timeType, Date time) {
		Criteria criteria = osConsultationDao.createCriteria(OsConsultation.class);
		if (groupType == 0) {
			// 按咨询员
			ProjectionList projectionList = Projections.projectionList();
			projectionList.add(Projections.groupProperty("Consultant.id"), "id");
			projectionList.add(Projections.rowCount(), "times");
			criteria.setProjection(projectionList);
		} else if (groupType == 1) {
			// 按咨询国家
			ProjectionList projectionList = Projections.projectionList();
			projectionList.add(Projections.groupProperty("CountryIntent.id"), "id");
			projectionList.add(Projections.rowCount(), "times");
			criteria.setProjection(projectionList);
		} else {
			criteria.setProjection(Projections.count("id")); 
		}
		if(timeType >= 0) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(time);
			if (timeType == 0) {
				// 按月份
				calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
				criteria.add(Restrictions.ge("CreateDate", calendar.getTime()));
				calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
				criteria.add(Restrictions.le("CreateDate", calendar.getTime()));
			} else if (timeType == 1) {
				// 按年份
				calendar.set(Calendar.MONTH, calendar.getActualMinimum(Calendar.MONTH));
				calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
				criteria.add(Restrictions.ge("CreateDate", calendar.getTime()));
				calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
				calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
				criteria.add(Restrictions.le("CreateDate", calendar.getTime()));
			}
		}
		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	public void updateExpired() {
		// 查询所有 状态为未签约，且时间过期 的咨询表
		Criteria criteria = osConsultationDao.createCriteria(OsConsultation.class);
		criteria.add(Restrictions.eq("State", OsConsultationState.UNSIGNED));
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -14);
		criteria.add(Restrictions.lt("CreateDate", calendar.getTime()));
		List<OsConsultation> osConsultations = criteria.list();
		// 修改状态为过期
		for(OsConsultation osConsultation : osConsultations) {
			osConsultation.setState(OsConsultationState.UNREASSIGNED);
			osConsultationDao.saveOrUpdate(osConsultation);
		}
	}

	public void setOsConsultationDao(OsConsultationDao osConsultationDao) {
		this.osConsultationDao = osConsultationDao;
	}
}
